package com.fandou.airobot.ui.alarm

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.blankj.utilcode.util.FragmentUtils
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ScreenUtils
import com.fandou.airobot.R
import com.fandou.airobot.database.Alarm
import com.fandou.airobot.database.AlarmConstants
import com.fandou.airobot.database.AlarmDatabase
import com.fandou.airobot.ui.widget.numberpicker.NumberPicker
import kotlinx.android.synthetic.main.add_alarm_fragment.*
import java.util.*

/**
 * @author       Jm
 * @date         2020/6/28 10:45
 * @description 添加或者编辑闹钟fragment
 */
const val MAX_HOUR = 23
const val MIN_HOUR = 0
const val MAX_MINUTE = 59
const val MIN_MINUTE = 0
const val MAX_SECOND = 59
const val MIN_SECOND = 0

/**
 *默认的闹钟
 */
const val DEFAULT_ALARM_HOUR = 15
const val DEFAULT_ALARM_MINUTE = 45
const val DEFAULT_ALARM_SECOND = 0

/**
 * 默认的倒计时
 */
const val DEFAULT_COUNTDOWN_HOUR = 0
const val DEFAULT_COUNTDOWN_MINUTE = 0
const val DEFAULT_COUNTDOWN_SECOND = 10


/**
 * @author       Jm
 * @date         2020/6/28 9:46
 * @description  添加或编辑闹钟fragment
 */
class AddAlarmFragment : Fragment(), TextWatcher {

    private val TAG = AddAlarmFragment::class.java.name

    /**
     * 标识当前的是添加闹钟还是添加倒计时
     */
    private var mAlarmType: Int = AlarmConstants.AlarmType.ALARM

    /**
     * 当前要编辑的闹钟或倒计时
     * default is null
     */
    private var mCurAlarm: Alarm? = null

    /**
     * 是否为编辑模式
     */
    private var isEditMode = false

    private lateinit var mViewModel: AlarmViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return layoutInflater.inflate(R.layout.add_alarm_fragment, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        init()
    }

    private fun init() {
        mAlarmType = requireArguments().getInt("type", AlarmConstants.AlarmType.ALARM)
        mCurAlarm = requireArguments().getParcelable("alarm")
        isEditMode = mCurAlarm != null
//        mViewModel = ViewModelProvider.NewInstanceFactory().create(AlarmViewModel::class.java) //不要使用这种方式创建，目前发现订阅无效，待探究
        mViewModel = ViewModelProviders.of(context as AppCompatActivity).get(AlarmViewModel::class.java)
        llTimeContainer.layoutParams.height = (ScreenUtils.getAppScreenHeight() * 0.45).toInt()
        initListener()
        initMode()
    }

    private fun initMode() {
        if (mAlarmType == AlarmConstants.AlarmType.ALARM) {
            initAlarmMode()
        } else {
            initCountdownMode()
        }

        //设置闹钟和倒计时通用的数据
        etRemark.addTextChangedListener(this)
        etRemark.setText(mCurAlarm?.remark)
        scSound.isChecked = mCurAlarm?.alertType == AlarmConstants.RemindType.ALERT_SOUND
        scSound.setOnCheckedChangeListener { buttonView, isChecked ->
            if (isChecked) {
                mCurAlarm?.alertType = AlarmConstants.RemindType.ALERT_SOUND
            } else {
                mCurAlarm?.alertType = AlarmConstants.RemindType.ALERT_VIBRATION
            }
        }
    }

    /**
     * 初始化  添加或编辑闹钟模式下的情况
     */
    private fun initAlarmMode() {
        if (mCurAlarm == null) {
            val time = Calendar.getInstance()
            time[Calendar.HOUR_OF_DAY] = DEFAULT_ALARM_HOUR
            time[Calendar.MINUTE] = DEFAULT_ALARM_MINUTE
            Log.d(TAG, "init the alarm:" + time.timeInMillis)
            mCurAlarm = Alarm(
                time.timeInMillis, etRemark.text.toString(),
                DEFAULT_ALARM_HOUR,
                DEFAULT_ALARM_MINUTE
                , scRepeat.isChecked
            )


            npHour.value = DEFAULT_ALARM_HOUR
            npMinute.value = DEFAULT_ALARM_MINUTE
        } else {
            npHour.value = mCurAlarm!!.hour
            npMinute.value = mCurAlarm!!.minute
            scRepeat.isChecked = mCurAlarm!!.repeat
        }

        npHour.setUnitText("点")
        npHour.maxValue = MAX_HOUR
        npHour.minValue = MIN_HOUR

        npMinute.setUnitText("分")
        npMinute.maxValue = MAX_MINUTE
        npMinute.minValue = MIN_MINUTE

        npSecond.visibility = View.GONE
    }

    /**
     * 初始化  添加或编辑倒计时模式下的情况
     */
    @Deprecated("暂不需要这样的倒计时功能")
    private fun initCountdownMode() {
        if (mCurAlarm == null) {
            mCurAlarm = Alarm(
                AlarmConstants.AlarmType.COUNTDOWN
                , if (scSound.isChecked) AlarmConstants.RemindType.ALERT_SOUND else AlarmConstants.RemindType.ALERT_VIBRATION
                , AlarmConstants.Period.ONCE
                , etRemark.text.toString()
                , DEFAULT_COUNTDOWN_HOUR
                , DEFAULT_COUNTDOWN_MINUTE
                , DEFAULT_COUNTDOWN_SECOND
                , ((DEFAULT_COUNTDOWN_HOUR * 60 * 60 * 1000 + DEFAULT_COUNTDOWN_MINUTE * 60 * 1000 + DEFAULT_COUNTDOWN_SECOND * 1000).toLong())
                , true
            )
            npHour.value = 0
            npMinute.value = 15
            npSecond.value = 0
        } else {
            npHour.value = mCurAlarm!!.hour
            npMinute.value = mCurAlarm!!.minute
            npSecond.value = mCurAlarm!!.second
        }
        npHour.maxValue = MAX_HOUR
        npHour.minValue = MIN_HOUR
        npMinute.maxValue = MAX_MINUTE
        npMinute.minValue = MIN_MINUTE
        npSecond.maxValue = MAX_SECOND
        npSecond.minValue = MIN_SECOND
        npHour.setUnitText("时")
        npMinute.setUnitText("分")
        npSecond.setUnitText("秒")
        npSecond.visibility = View.VISIBLE
        npMinute.setGravity(NumberPicker.Gravity.CENTER)
    }


    private fun initListener() {
        scRepeat.setOnCheckedChangeListener { buttonView, isChecked -> mCurAlarm?.setRepeat(isChecked) }

        // The hour picker listener
        npHour.setOnValueChangedListener { picker, oldVal, newVal ->
            Log.d(TAG, "hour:${newVal}")
            mCurAlarm!!.hour = newVal
            updateAlarmMill()
            updateCountdownMill()
        }

        // The minute picker listener
        npMinute.setOnValueChangedListener { picker, oldVal, newVal ->
            Log.d(TAG, "minute:${newVal}")
//            mMinute = newVal
            mCurAlarm!!.minute = newVal

            val time = Calendar.getInstance()
            time[Calendar.MINUTE] = newVal
            mCurAlarm!!.setTime(time.timeInMillis)
            updateAlarmMill()
            updateCountdownMill()
        }

        //the second picker listener
        npSecond.setOnValueChangedListener { picker, oldVal, newVal ->
            Log.d(TAG, "second:${newVal}")
            mCurAlarm!!.second = newVal

            updateAlarmMill()
            updateCountdownMill()
        }


        // Save the alarm or countdown
        titleBar.setOnRightClickListener {
            if (mAlarmType == AlarmConstants.AlarmType.ALARM) {
                saveAlarm()
            } else {
                saveCountdown()
            }
        }
    }

    /**
     * Update the countdown  millisecond
     * 当且仅当 在倒计时模式下才执行
     */
    private fun updateCountdownMill() {
        if (mAlarmType == AlarmConstants.AlarmType.COUNTDOWN) {
            mCurAlarm!!.countdownTimestamp = (mCurAlarm!!.hour * 60 * 60 * 1000 + mCurAlarm!!.minute * 60 * 1000 + mCurAlarm!!.second * 1000).toLong()
        }
        Log.d(TAG, "当前倒计时:${mCurAlarm!!.countdownTimestamp}")
    }

    /**
     * Update the alarm timestamp
     */
    private fun updateAlarmMill() {
        val time = Calendar.getInstance()
        Log.d(TAG, "hour:${mCurAlarm!!.hour}}")
        Log.d(TAG, "minute:${mCurAlarm!!.minute}}")
        time[Calendar.HOUR_OF_DAY] = mCurAlarm!!.hour
        time[Calendar.MINUTE] = mCurAlarm!!.minute
        time[Calendar.SECOND] = 0
        mCurAlarm!!.setTime(time.timeInMillis)

    }


    /**
     * 保存闹钟
     */
    private fun saveAlarm() {
        val insertCount: Long

        if (isEditMode) {
            //每次保存，都把这个alarm都开启
            mCurAlarm!!.setEnable(true)
            insertCount = AlarmDatabase.getInstance().alarmDao().updateAlarm(mCurAlarm).toLong()
            if (insertCount > 0) {
                Log.d(TAG, "updateAlarm:" + GsonUtils.toJson(mCurAlarm))
                mViewModel.updateAlarmLiveData.value = mCurAlarm
                FragmentUtils.pop(parentFragmentManager)
            }

        } else {
            val rowIdList = AlarmDatabase.getInstance().alarmDao().insertAlarm(mCurAlarm) as MutableList<Long>
            Log.d(TAG, "insertAlarm:" + GsonUtils.toJson(rowIdList))
            //rowIdList.size大于0代表成功插入数据库，返回了唯一id，需要为这个post出去的实体赋值它的id。
            if (rowIdList.size > 0) {
                mCurAlarm!!.setId(rowIdList[0])
                mViewModel.addAlarmLiveData.value = mCurAlarm
                FragmentUtils.pop(parentFragmentManager)
//                NavHostFragment.findNavController(this).navigateUp()
            } else {
                Log.e(TAG, "保存闹钟失败：${GsonUtils.toJson(rowIdList)}")
            }
        }
    }


    /**
     * 保存倒计时
     */
    private fun saveCountdown() {
        if (mCurAlarm!!.hour == 0 && mCurAlarm!!.minute == 0 && mCurAlarm!!.second == 0) return
        val insertCount: Long
        if (isEditMode) {
            insertCount = AlarmDatabase.getInstance().alarmDao().updateAlarm(mCurAlarm).toLong()
            if (insertCount > 0) {
                mViewModel.updateAlarmLiveData.value = mCurAlarm
                FragmentUtils.pop(parentFragmentManager)
//                NavHostFragment.findNavController(this).navigateUp()
            } else {
                Log.d(TAG, "更新倒计时失败：${insertCount}")
            }
        } else {
            val rowIdList = AlarmDatabase.getInstance().alarmDao().insertAlarm(mCurAlarm) as MutableList<Long>
            if (rowIdList.size > 0) {
                mCurAlarm!!.setId(rowIdList[0])
                mViewModel.addAlarmLiveData.value = mCurAlarm
                FragmentUtils.pop(parentFragmentManager)
//                NavHostFragment.findNavController(this).navigateUp()
            } else {
                Log.e(TAG, "保存倒计时失败：${GsonUtils.toJson(rowIdList)}")
            }
        }
    }


    override fun afterTextChanged(s: Editable?) {
        mCurAlarm?.setRemark(s.toString())
    }

    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
    }

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
    }

    override fun onDestroy() {
        etRemark?.removeTextChangedListener(this)
        super.onDestroy()
    }

    companion object {

        /**
         * @param isAddMode 标识当前界面是否添加闹钟状态
         * @param alarmType  功能类型。{@link AlarmConstants.AlarmType}
         * @param alarm   当编辑时必传
         */
        @JvmStatic
        fun newInstance(isAddMode: Boolean, alarmType: Int, alarm: Alarm? = null): AddAlarmFragment {
            return AddAlarmFragment().also { fragment ->
                fragment.arguments = Bundle().also {
                    it.putBoolean("isAddMode", isAddMode)
                    it.putInt("type", alarmType)
                    it.putParcelable("alarm", alarm)
                }
            }
        }
    }
}